package com.docking.heylo.service.impl;

import com.docking.heylo.ThreadContext;
import com.docking.heylo.dao.entity.SysUser;
import com.docking.heylo.dao.entity.SysUserExample;
import com.docking.heylo.dao.mapper.SysUserMapper;
import com.docking.heylo.enums.EUserLocks;
import com.docking.heylo.exception.GeneralException;
import com.docking.heylo.pojo.Audience;
import com.docking.heylo.service.ISysRoleResourceService;
import com.docking.heylo.service.ISysUserService;
import com.docking.heylo.utils.JwtHelper;
import com.docking.heylo.web.utils.MD5;
import com.docking.heylo.web.dto.SysUserDto;
import com.docking.heylo.web.vo.LoginResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class SysUserServiceImpl implements ISysUserService {


    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private ISysRoleResourceService resourceService;


    private static final String defaultPassword = "123456";

    @Autowired
    private Audience audience;

    @Override
    public LoginResult login(SysUserDto userDto) {
        SysUser user = selectByExample(new SysUser(){{
            setUserName(userDto.getUserName());
        }});

        if(user != null && !user.getPassword().equals(encryptionUserPassword(userDto.getPassword(),user.getSalt()))){
            throw new GeneralException("用户名或密码错误！");
        }else if(user.getLocks().intValue() == EUserLocks.DISABLE.getValue()){
            throw new GeneralException("帐号被锁定，请联系管理员!");
        }

        LoginResult result = buildResult(user);
        result.setToken(buildToken(user.getId(), user.getUserName(), 123));

        sysUserMapper.updateByPrimaryKeySelective(new SysUser(){{
            setId(user.getId());
            setLastLoginIp(ThreadContext.requestIP());
            setLastLoginTime(new Date());
            setLoginCount(user.getLoginCount() + 1);
        }});

        result.setMenus(resourceService.resourcesByRoleId(user.getRoleId()));

        return result;
    }

    @Override
    public LoginResult userInfo() {
        SysUser user = selectByExample(new SysUser(){{
            setId(ThreadContext.userId());
        }});

        return buildResult(user);
    }

    @Override
    public void editPassword(SysUserDto userDto) {
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(ThreadContext.userId());
        editUserPassword(userDto.getPassword(), sysUser.getSalt(), sysUser.getId());
    }

    @Override
    public void saveSysUser(SysUserDto userDto) {
        if(selectCountByUserName(userDto.getUserName()) > 0){
            throw new GeneralException("用户名已存在");
        }

        String uuid = UUID.randomUUID().toString().replace("-","");
        sysUserMapper.insertSelective(new SysUser(){{
            setUserName(userDto.getUserName());
            setPassword(encryptionUserPassword(defaultPassword,uuid));
            setSex(userDto.getSex());
            setRealName(userDto.getRealName());
            setIdCard(userDto.getIdCard());
            setPhone(userDto.getPhone());
            setEmail(userDto.getEmail());
            setAddress(userDto.getAddress());
            setCrtAt(new Date());
            setCrtBy(ThreadContext.userId());
            setStatus(EUserLocks.NORMAL.getValue());
            setAvatar("");
            setSalt(uuid);
            setRoleId(userDto.getRoleId());
            setLoginCount(0);
            setLocks(EUserLocks.NORMAL.getValue());
        }});
    }

    @Override
    public PageInfo<Map<String, Object>> sysUserList(SysUserDto userDto) {
        PageHelper.startPage(userDto.getPageNumber(), userDto.getSize());
        return new PageInfo(sysUserMapper.sysUserList(userDto.getUserName(),
                userDto.getPhone(), userDto.getRealName()));
    }

    @Override
    public SysUser selectById(Integer userId) {
        return sysUserMapper.selectByPrimaryKey(userId);
    }

    @Override
    public void editUserInfo(SysUserDto userDto) {
        sysUserMapper.updateByPrimaryKeySelective(new SysUser(){{
            setId(userDto.getUserId());
            setSex(userDto.getSex());
            setRealName(StringUtils.isEmpty(userDto.getRealName()) ? null : userDto.getRealName());
            setIdCard(StringUtils.isEmpty(userDto.getIdCard()) ? null : userDto.getIdCard());
            setPhone(StringUtils.isEmpty(userDto.getPhone()) ? null : userDto.getPhone());
            setEmail(StringUtils.isEmpty(userDto.getEmail()) ? null : userDto.getEmail());
            setAddress(StringUtils.isEmpty(userDto.getAddress()) ? null : userDto.getAddress());
            setRoleId(userDto.getRoleId());
            setLocks(userDto.getLocks());
        }});
    }

    @Override
    public void resetPassword(SysUserDto sysUser) {
        SysUser user = sysUserMapper.selectByPrimaryKey(sysUser.getUserId());
        editUserPassword(defaultPassword, user.getSalt(), user.getId());
    }

    public void editUserPassword(String password, String salt, int userId){
        sysUserMapper.updateByPrimaryKeySelective(new SysUser(){{
            setId(userId);
            setPassword(encryptionUserPassword(password, salt));
        }});
    }

    @Override
    public void disableActivation(SysUserDto sysUser) {
        sysUserMapper.updateByPrimaryKeySelective(new SysUser(){{
            setId(sysUser.getUserId());
            setLocks(sysUser.getLocks());
        }});
    }

    public long selectCountByUserName(String userName){
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        criteria.andUserNameEqualTo(userName);
        return sysUserMapper.countByExample(example);
    }

    public SysUser selectByExample(SysUser user){
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        if(!StringUtil.isEmpty(user.getUserName())){
            criteria.andUserNameEqualTo(user.getUserName());
        }

        if(user.getId() != null){
            criteria.andIdEqualTo(user.getId());
        }

        List<SysUser> users = sysUserMapper.selectByExample(example);
        return users.size() > 0 ? users.get(0) : null;
    }

    /***
     * 加密用户密码
     *
     * @param password
     * @return
     */
    public String encryptionUserPassword(String password,String salt){
        return MD5.getMD5(MD5.MD5Encode(password,salt));
    }

    public LoginResult buildResult(SysUser user){
        LoginResult result = new LoginResult();
        result.setUserName(user.getUserName());

        return result;
    }

    /***
     * 生产Token
     * @param userId
     * @param userName
     * @param roleId
     * @return
     */
    private String buildToken(Integer userId, String userName, Integer roleId){
        return JwtHelper.constructJWT(userId, roleId, userName,
                audience.getClientId(),
                audience.getName(),
                audience.getExpiresSecond(),
                audience.getBase64Secret());
    }



    @Override
    public long countByRoleId(Integer id) {
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        criteria.andRoleIdEqualTo(id);
        return sysUserMapper.countByExample(example);
    }

    @Override
    public Map<String, Object> registerStatistics() {
        return sysUserMapper.registerStatistics();
    }





}
